package com.admin.controller;

import com.admin.service.AdminMenuService;
import com.admin.service.AdminService;
import com.admin.util.CommonUtil;
import com.admin.util.LogUtil;
import com.admin.util.Md5Util;
import com.admin.util.Result;
import com.data.entity.Admin;
import com.data.entity.AdminMenu;
import com.data.entity.Role;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/login/")
@Api(tags = "登录管理")
/**
 * 登录管理
 */
public class LoginController {
    @Resource
    private AdminService adminService;
    @Resource
    private AdminMenuService adminMenuService;


    private Logger logger = LogUtil.getBussinessLogger();

    /**
     * 注销登录
     * @return
     */
    @GetMapping("loginOut")
    @ApiOperation("注销")
    public Result loginOut() {
        Result result = new Result();
        try {
            Subject subject = SecurityUtils.getSubject();
            /*Admin admin = (Admin) subject.getSession().getAttribute("user");
            admin.setOnline(0);
            adminService.edit(admin);*/
            //注销
            subject.logout();
            result.setCode(Result.Code.SUCCESS);
            logger.info("---注销登录---");
        } catch (Exception e) {
            logger.error(e.getMessage());
            result.setCode(Result.Code.SYSTEMERROR);
        }
        return result;
    }

    /**
     * 登录
     * @param username  登录管理员账号
     * @param password  账号密码
     * @return
     */
    @PostMapping("loginIn")
    @ApiOperation("登录")
    public Result loginIn(String username, String password) {
        Result result = new Result();
        try {
                // 从SecurityUtils里边创建一个 subject
                Subject subject = SecurityUtils.getSubject();
                String pwd = Md5Util.encode(username + password);//加密后的密码
                // 在认证提交前准备 token（令牌）
                UsernamePasswordToken token = new UsernamePasswordToken(username, pwd);
                // 执行认证登陆
                subject.login(token);
                logger.info("---用户登录成功----" + username);
                //根据权限，指定返回数据
                Role role = adminService.getRole(username);//查询角色名称
                if (CommonUtil.isEmpty(role)) {
                    result.setMessage(Result.Code.ROLEBAN, "权限错误！");
                    return result;
                }
                Admin admin = adminService.getAdmin(username);
                if (CommonUtil.isEmpty(admin)){
                    result.setMessage(Result.Code.ROLEBAN, "账号被冻结，请联系系统管理员！");
                    return result;
                }
                admin.setRole(role);
                if (!"admin".equals(role.getName())) {//普通用户
                    result.setCode(Result.Code.SUCCESS);
                    subject.getSession().setAttribute("user", admin);
                    result.setData(admin);
                    return result;
                }
                if ("admin".equals(role.getName())) {//管理员
                    result.setCode(Result.Code.SUCCESS);
                    subject.getSession().setAttribute("user", admin);
                    result.setData(admin);
                    return result;
                }
                result.setCode(Result.Code.ROLEBAN);
                result.setMessage(Result.Code.ROLEBAN, "权限错误！");
        } catch (AccountException a) {
            logger.error(a.getMessage());
            result.setMessage(Result.Code.PARAMERROR, a.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            result.setMessage(Result.Code.ROLEBAN, "账号被冻结，请联系系统管理员！");
        }
        return result;

    }

    /**
     * 管留言信息
     * @return
     */
    @PostMapping("myInfo")
    @ApiOperation("管理员信息")
    public Result myInfo() {
        Result result = new Result();
        try {
            Subject subject = SecurityUtils.getSubject();
            Admin user = (Admin) subject.getSession().getAttribute("user");
            result.setCode(Result.Code.SUCCESS);
            result.setData(user);
        } catch (Exception e) {
            logger.error(e.getMessage());
            result.setCode(Result.Code.SYSTEMERROR);
        }
        return result;
    }

    /**
     * 修改密码
     * @param id    管理员id
     * @param oldPwd    旧密码
     * @param newPwd    新密码
     * @return
     */
    @PostMapping("updatePwd")
    @ApiOperation("修改密码")
    public Result updatePwd(@RequestParam("id") Long id, @RequestParam("oldPwd") String oldPwd, @RequestParam("newPwd") String newPwd) {
        Result result = new Result();
        try {
            Admin admin = adminService.getById(id);
            //使用MD5加密密码
            String oldPwd1 = Md5Util.encode(admin.getUsername() + oldPwd);//验证旧密码
            String password = Md5Util.encode(admin.getUsername() + newPwd);  //加密新密码
            System.out.println("加密旧密码 = [" + oldPwd1);
            if (oldPwd1.equals(admin.getPassword())) {
                adminService.updatePwd(id, password);
                result.setCode(Result.Code.SUCCESS);
            } else {
                result.setMessage(Result.Code.FAILED, "原始密码错误");
            }
        } catch (Exception e) {
            result.setCode(Result.Code.SYSTEMERROR);
            logger.error(e.getMessage());
        }
        return result;
    }

    /**
     * 查询用户权限菜单
     *
     * @return
     */
    @GetMapping("menus")
    @ApiOperation("用户权限菜单")
    public Result menus() {
        Result result = new Result();
        try {
            // 从SecurityUtils里边创建一个 subject
            Subject subject = SecurityUtils.getSubject();
            Admin admin = (Admin) subject.getSession().getAttribute("user");
            //查询角色菜单
            List<AdminMenu> menus = adminMenuService.listByRoleId(admin.getRoleId());
            result.setCode(Result.Code.SUCCESS);
            result.setData(menus);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            result.setCode(Result.Code.SYSTEMERROR);
        }
        return result;

    }
}
